package com.enjoy.concurrent.ch4;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "enjoy")
public class ExpressCondition {

    public static final String SHANGHAI = "SHANGHAI";

    public String site;

    public int distance;

    private Lock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    public ExpressCondition(String site, int distance) {
        this.site = site;
        this.distance = distance;
    }

    void changeDistance() {
        try {
            lock.lock();
            this.distance = 100;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    void changeSite() {
        try {
            lock.lock();
            this.site = "SHANGHAI";
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    void waitDistance() {
        log.info("当前的距离是:{}", this.distance);
        try {
            lock.lock();
            while (this.distance < 100) {
                condition.await();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        log.info("当前的距离是:{}", this.distance);
    }

    void waitSite() {
        log.info("当前的地址是:{}", this.site);
        try {
            lock.lock();
            while (!SHANGHAI.equals(this.site)) {
                condition.await();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        log.info("当前的地址是:{}", this.site);
    }

    public static void main(String[] args) throws InterruptedException {
        ExpressCondition expressCondition = new ExpressCondition("BEIJING", 0);
        new Thread(expressCondition::waitDistance).start();
        new Thread(expressCondition::waitSite).start();

        Thread.sleep(10000);

        expressCondition.changeSite();
        expressCondition.changeDistance();
    }
}
